package com.tbit.uqbike.quartz;

import com.tbit.uqbike.constant.ReportDataType;
import com.tbit.uqbike.object.pojo.Account;
import com.tbit.uqbike.object.pojo.AccountConfig;
import com.tbit.uqbike.object.pojo.statistics.LowBatteryHour;
import com.tbit.uqbike.object.pojo.statistics.ReportDataDaySta;
import com.tbit.uqbike.service.base.RedisService;
import com.tbit.uqbike.webmanager.dao.core.*;
import com.tbit.uqbike.webmanager.dao.log.DispatchLogDao;
import com.tbit.uqbike.webmanager.dao.log.MoveLogDao;
import com.tbit.uqbike.webmanager.dao.log.RepairLogDao;
import com.tbit.uqbike.webmanager.business.vehicle_operation_report.dao.stat.LowBatteryHourDao;
import com.tbit.uqbike.webmanager.dao.stat.ReportDataDayStaDao;
import com.tbit.utils.DateTimeUtil;
import com.tbit.utils.NullUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author HZW
 * @ClassName SundryDataQuartz
 * @Description 数据统计的定时任务
 * @date 2022/1/5 19:15
 * @Version 1.0
 */
@Component
public class SundryDataQuartz {
    private static List<Integer> detects = null;
    private static List<Account> accounts = null;
    DecimalFormat decimalFormat = new DecimalFormat("0.00");
    @Resource
    private AccountDao accountDao;
    @Resource
    private StatDataDao statDataDao;
    @Resource
    private RedisService redisService;
    @Resource
    private RideLogDao rideLogDao;
    @Resource
    private ReportDataDayStaDao reportDataDayStaDao;
    @Resource
    private MachineDao machineDao;
    @Resource
    private RepairLogDao repairLogDao;
    @Resource
    private MachineFaultDao machineFaultDao;
    @Resource
    private DispatchLogDao dispatchLogDao;
    @Resource
    private MoveLogDao moveLogDao;
    @Resource
    private AccountConfigDao accountConfigDao;
    @Resource
    private LowBatteryHourDao lowBatteryHourDao;

    /**
     * 统计车辆数据
     */
    @Scheduled(cron = "0 30 4 * * ?")
    public void statisticsUser() {
        Map<String, Object> params = new HashMap<>(8);
        params.put("type", "3");
        /**获取三级区域的信息*/
        accounts = accountDao.getAccountByType(params);
        params.clear();
        /**获取三级区域的id*/
        detects = accounts.stream().map(Account::getAccountId).collect(Collectors.toList());
        /**前一天的时间*/
        String time = DateTimeUtil.getYesterdayTime();
        /**获取今天的年月日*/
        String toDay = DateTimeUtil.getNowTimeYMD();
        detects.forEach(accountId -> {
            params.put("accountId", accountId);
            /***获取昨天的开始时间*/
            params.put("startTime", DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)));
            /**获取今天的开始时间*/
            params.put("endTime", DateTimeUtil.DateTimeToStringYMD(new Date()));

            /**统计每日车辆周转率*/
            params.put("type", ReportDataType.DAILY_MACHINE);
            /**查看最近一次的预统计数据，防止有哪一天没有统计*/
            ReportDataDaySta recentlyData = reportDataDayStaDao.getRecentlyData(params);
            if (!NullUtils.isEmpty(recentlyData)) {
                /**查看添加时间是否是今天,且日期是否昨天*/
                if (!DateTimeUtil.formatDateYMD(recentlyData.getAddTime()).equals(toDay) &&
                        !recentlyData.getDataDate().equals(DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)))) {
                    Map<String, Object> recentlyMap = new HashMap<>(5);
                    recentlyMap.put("accountId", accountId);
                    recentlyMap.put("startTime", recentlyData.getDataDate());
                    recentlyMap.put("endTime", DateTimeUtil.DateTimeToStringYMD(new Date()));
                    /**当前全部车辆数*/
                    Integer machineTotal = machineDao.selectById(accountId).size();
                    /**时间内去重的车辆数*/
                    List<Map<String, Object>> machineNum = rideLogDao.getMachineNumDay(recentlyMap);
                    if (!machineNum.isEmpty()) {
                        for (Map<String, Object> machineMap : machineNum) {
                            machineMap.put("type", ReportDataType.DAILY_MACHINE);
                            machineMap.put("dataTotal", machineTotal);
                            machineMap.put("completeEta", machineTotal == 0 ? "0" : decimalFormat.format((float) Integer.parseInt(machineMap.get("dataCount").toString()) / machineTotal * 100));
                        }
                        /**新增数据*/
                        reportDataDayStaDao.insertBatchData(machineNum);
                    }
                } else {
                    recentlyData.setAddTime(new Date());
                    reportDataDayStaDao.updateData(recentlyData);
                }
            } else {
                /**当前全部车辆数*/
                Integer machineTotal = machineDao.selectById(accountId).size();
                /**时间内去重的车辆数*/
                List<Map<String, Object>> machineNum = rideLogDao.getMachineNumDay(params);
                if (!machineNum.isEmpty()) {
                    for (Map<String, Object> machineMap : machineNum) {
                        machineMap.put("type", ReportDataType.DAILY_MACHINE);
                        machineMap.put("dataTotal", machineTotal);
                        machineMap.put("completeEta", machineTotal == 0 ? "0" : decimalFormat.format((float) Integer.parseInt(machineMap.get("dataCount").toString()) / machineTotal * 100));
                    }
                    /**新增数据*/
                    reportDataDayStaDao.insertBatchData(machineNum);
                }
            }

            /**统计每日维修完成率*/
            params.put("type", ReportDataType.DAILY_MAINTAIN);
            /**获取时间内维修完成率的记录*/
            /**查看最近一次的预统计数据，防止有哪一天没有统计*/
            ReportDataDaySta reByMaintain = reportDataDayStaDao.getRecentlyData(params);
            if (!NullUtils.isEmpty(reByMaintain)) {
                /**查看添加时间是否是今天,且日期是否昨天*/
                if (!DateTimeUtil.formatDateYMD(reByMaintain.getAddTime()).equals(toDay) &&
                        !reByMaintain.getDataDate().equals(DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)))) {
                    Map<String, Object> recentlyMap = new HashMap<>(5);
                    recentlyMap.put("accountId", accountId);
                    recentlyMap.put("startTime", reByMaintain.getDataDate());
                    recentlyMap.put("endTime", DateTimeUtil.DateTimeToStringYMD(new Date()));
                    /**获取未记录时间内的维修记录*/
                    List<Map<String, Object>> maintainNum = repairLogDao.getMaintainNumDay(recentlyMap);
                    if (!maintainNum.isEmpty()) {
                        for (Map<String, Object> maintain : maintainNum) {
                            maintain.put("endTime", maintain.get("dataDate") + " 23:59:59");
                            maintain.put("machineIds", Arrays.asList(maintain.get("machineIds").toString().split(",")));
                            /**每天的运维标记的工单数*/
                            Integer maintainTotal = machineFaultDao.getFaultByTime(maintain);
                            maintain.put("type", ReportDataType.DAILY_MAINTAIN);
                            maintain.put("dataTotal", maintainTotal);
                            maintain.put("completeEta", maintainTotal == 0 ? "0" : decimalFormat.format((float) Integer.parseInt(maintain.get("dataCount").toString()) / maintainTotal * 100));
                        }
                        reportDataDayStaDao.insertBatchData(maintainNum);
                    }
                } else {
                    reByMaintain.setAddTime(new Date());
                    reportDataDayStaDao.updateData(reByMaintain);
                }

            } else {
                List<Map<String, Object>> maintainNum = repairLogDao.getMaintainNumDay(params);
                if (!maintainNum.isEmpty()) {
                    for (Map<String, Object> maintain : maintainNum) {
                        maintain.put("endTime", maintain.get("dataDate") + " 23:59:59");
                        maintain.put("machineIds", Arrays.asList(maintain.get("machineIds").toString().split(",")));
                        /**每天的运维标记的工单数*/
                        Integer maintainTotal = machineFaultDao.getFaultByTime(maintain);
                        maintain.put("type", ReportDataType.DAILY_MAINTAIN);
                        maintain.put("dataTotal", maintainTotal);
                        maintain.put("completeEta", maintainTotal == 0 ? "0" : decimalFormat.format((float) Integer.parseInt(maintain.get("dataCount").toString()) / maintainTotal * 100));
                    }
                    reportDataDayStaDao.insertBatchData(maintainNum);
                }
            }


            /**统计调度车辆有效率*/
            params.put("type", ReportDataType.DAILY_DISPATCH);
            /**查看最近一次的预统计数据，防止有哪一天没有统计*/
            ReportDataDaySta reByDispatch = reportDataDayStaDao.getRecentlyData(params);
            if (!NullUtils.isEmpty(reByDispatch)) {
                /**查看添加时间是否是今天,且日期是否昨天*/
                if (!DateTimeUtil.formatDateYMD(reByDispatch.getAddTime()).equals(toDay) &&
                        !reByDispatch.getDataDate().equals(DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)))) {
                    Map<String, Object> recentlyMap = new HashMap<>(5);
                    recentlyMap.put("accountId", accountId);
                    recentlyMap.put("startTime", reByDispatch.getDataDate());
                    recentlyMap.put("endTime", DateTimeUtil.DateTimeToStringYMD(new Date()));
                    /**获取昨天前所有的调度记录*/
                    List<Map<String, Object>> dispatchNum = dispatchLogDao.getDispatchNumDay(recentlyMap);
                    if (!dispatchNum.isEmpty()) {
                        for (Map<String, Object> dispatch : dispatchNum) {
                            dispatch.put("userCodes", Arrays.asList(dispatch.get("userCodes").toString().split(",")));
                            dispatch.put("endTime", dispatch.get("dataDate") + " 23:59:59");
                            /**获取昨天的骑行的调度车辆*/
                            Integer dataCount = rideLogDao.getRidingMachine(dispatch);
                            /**获取昨天有效的调度记录*/
                            Integer dispatchTotal = Integer.parseInt(dispatch.get("dataTotal").toString());
                            dispatch.put("type", ReportDataType.DAILY_DISPATCH);
                            dispatch.put("dataCount", dataCount);
                            dispatch.put("completeEta", dispatchTotal == 0 ? "0" : decimalFormat.format((float) dataCount / dispatchTotal * 100));
                        }
                        reportDataDayStaDao.insertBatchData(dispatchNum);
                    }
                } else {
                    reByDispatch.setAddTime(new Date());
                    reportDataDayStaDao.updateData(reByDispatch);
                }
            } else {
                /**获取昨天前所有的调度记录*/
                List<Map<String, Object>> dispatchNum = dispatchLogDao.getDispatchNumDay(params);
                if (!dispatchNum.isEmpty()) {
                    for (Map<String, Object> dispatch : dispatchNum) {
                        dispatch.put("userCodes", Arrays.asList(dispatch.get("userCodes").toString().split(",")));
                        dispatch.put("endTime", dispatch.get("dataDate") + " 23:59:59");
                        /**获取昨天的骑行的调度车辆*/
                        Integer dataCount = rideLogDao.getRidingMachine(dispatch);
                        /**获取每天有效的调度记录*/
                        Integer dispatchTotal = Integer.parseInt(dispatch.get("dataTotal").toString());
                        dispatch.put("type", ReportDataType.DAILY_DISPATCH);
                        dispatch.put("dataCount", dataCount);
                        dispatch.put("completeEta", dispatchTotal == 0 ? "0" : decimalFormat.format((float) dataCount / dispatchTotal * 100));
                    }
                    reportDataDayStaDao.insertBatchData(dispatchNum);
                }
            }


            /**统计挪车车辆有效率*/
            params.put("type", ReportDataType.DAILY_SUPERZONE);
            /**查看最近一次的预统计数据，防止有哪一天没有统计*/
            ReportDataDaySta moveData = reportDataDayStaDao.getRecentlyData(params);
            if (!NullUtils.isEmpty(moveData)) {
                /**查看添加时间是否是今天,且日期是否昨天*/
                if (!DateTimeUtil.formatDateYMD(moveData.getAddTime()).equals(toDay) &&
                        !moveData.getDataDate().equals(DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)))) {
                    Map<String, Object> recentlyMap = new HashMap<>(5);
                    recentlyMap.put("accountId", accountId);
                    recentlyMap.put("startTime", moveData.getDataDate());
                    recentlyMap.put("endTime", DateTimeUtil.DateTimeToStringYMD(new Date()));
                    /**获取昨天前所有的有效挪车记录*/
                    List<Map<String, Object>> moveNumDay = moveLogDao.getMoveNumDay(recentlyMap);
                    if (!moveNumDay.isEmpty()) {
                        for (Map<String, Object> moveNum : moveNumDay) {
                            /**获取一天内所有的挪车记录*/
                            moveNum.put("startTime", moveNum.get("dataDate"));
                            moveNum.put("endTime", moveNum.get("dataDate") + " 23:59:59");
                            Integer totalDay = Integer.parseInt(moveLogDao.selectNumByDay(moveNum).get("dataCount").toString());
                            moveNum.put("type", ReportDataType.DAILY_SUPERZONE);
                            moveNum.put("dataTotal", totalDay);
                            Integer validNum = Integer.parseInt(moveNum.get("dataCount").toString());
                            moveNum.put("completeEta", totalDay == 0 ? "0" : decimalFormat.format((float) validNum / totalDay * 100));

                        }
                        reportDataDayStaDao.insertBatchData(moveNumDay);
                    }
                } else {
                    moveData.setAddTime(new Date());
                    reportDataDayStaDao.updateData(moveData);
                }
            } else {
                /**获取昨天前所有的有效挪车记录*/
                List<Map<String, Object>> moveNumDay = moveLogDao.getMoveNumDay(params);
                if (!moveNumDay.isEmpty()) {
                    for (Map<String, Object> moveNum : moveNumDay) {
                        /**获取一天内所有的挪车记录*/
                        moveNum.put("startTime", moveNum.get("dataDate"));
                        moveNum.put("endTime", moveNum.get("dataDate") + " 23:59:59");
                        Integer totalDay = Integer.parseInt(moveLogDao.selectNumByDay(moveNum).get("dataCount").toString());
                        moveNum.put("type", ReportDataType.DAILY_SUPERZONE);
                        moveNum.put("dataTotal", totalDay);
                        Integer validNum = Integer.parseInt(moveNum.get("dataCount").toString());
                        moveNum.put("completeEta", totalDay == 0 ? "0" : decimalFormat.format((float) validNum / totalDay * 100));

                    }
                    reportDataDayStaDao.insertBatchData(moveNumDay);
                }
            }
        });
    }

    //@Scheduled(cron = "0 */30 * * * ?")
    public void statisticsLowVoltage() {
        Map<String, Object> params = new HashMap<>(8);
        params.put("type", "3");
        /**获取三级区域的信息*/
        List<Account> accountList = accountDao.getAccountByType(params);
        params.clear();
        /**获取三级区域的id*/
        List<Integer> AccountIdList = accountList.stream().map(Account::getAccountId).collect(Collectors.toList());
        AccountIdList.forEach(accountId -> {
            String nowTime = DateTimeUtil.getNowTime();
            /**统计低电车辆占比*/
            params.put("type", ReportDataType.DAILY_LOW_VOLTAGE);
            params.put("accountId", accountId);
            /**获取半个小时前的时间*/
            params.put("startTime", DateTimeUtil.beforeOneHourToNowDate());
            params.put("endTime", nowTime);
            /**查看最近一次的预统计数据，防止有哪一天没有统计*/
            /***/
            LowBatteryHour reLowData = lowBatteryHourDao.getRecentlyData(params);
            /**获取区域的低点阈值*/
            AccountConfig accountConfig = accountConfigDao.getById(accountId);
            if (!NullUtils.isEmpty(reLowData)) {
                /**查看日期是否前半个小时的*/
                if (!reLowData.getDataDate().equals(DateTimeUtil.beforeOneHourToNowDate())) {
                    /**查看区域所有车辆的电量信息*/
                    List<Map<String, Object>> machineList = machineDao.getMachineSoc(params);
                    if (!NullUtils.isEmpty(accountConfig) &&
                            !NullUtils.isEmpty(accountConfig.getSocLimit()) &&
                            !NullUtils.isEmpty(machineList)) {
                        /**低点阈值*/
                        Integer socLimit = accountConfig.getSocLimit();
                        /**排查低电量车辆*/
                        Long lowMachine = machineList.stream().filter(item -> Integer.parseInt(item.get("socPercent").toString()) < socLimit).count();
                        /**当前全部车辆数*/
                        int machineTotal = machineDao.selectById(accountId).size();

                        Map<String, Object> item = new HashMap<>();
                        item.put("accountId", accountId);
                        item.put("type", ReportDataType.DAILY_LOW_VOLTAGE);
                        item.put("completeEta", machineTotal == 0 ? "0" : decimalFormat.format((float) lowMachine / machineTotal * 100));
                        item.put("dataDate", nowTime);
                        List<Map<String, Object>> itemMapList = new LinkedList<>();
                        itemMapList.add(item);
                        /***/
                        lowBatteryHourDao.insertBatchData(itemMapList);
                    }
                } else {
                    reLowData.setAddTime(new Date());
                    /***/
                    lowBatteryHourDao.updateData(reLowData);
                }
            } else {
                /**查看区域所有车辆的电量信息*/
                List<Map<String, Object>> machineList = machineDao.getMachineSoc(params);
                if (!NullUtils.isEmpty(accountConfig) &&
                        !NullUtils.isEmpty(accountConfig.getSocLimit()) &&
                        !NullUtils.isEmpty(machineList)) {
                    /**低点阈值*/
                    Integer socLimit = accountConfig.getSocLimit();
                    /**排查低电量车辆*/
                    Long lowMachine = machineList.stream().filter(item -> Integer.parseInt(item.get("socPercent").toString()) < socLimit).count();
                    /**当前全部车辆数*/
                    int machineTotal = machineDao.selectById(accountId).size();

                    Map<String, Object> item = new HashMap<>();
                    item.put("accountId", accountId);
                    item.put("type", ReportDataType.DAILY_LOW_VOLTAGE);
                    item.put("completeEta", machineTotal == 0 ? "0" : decimalFormat.format((float) lowMachine / machineTotal * 100));
                    item.put("dataDate", nowTime);
                    List<Map<String, Object>> itemMapList = new LinkedList<>();
                    itemMapList.add(item);
                    /***/
                    lowBatteryHourDao.insertBatchData(itemMapList);
                }
            }

        });
    }

}
